import axios from 'axios';
import qs from 'qs';
import store from '@/store/index';
import { getUrlParam } from './index';
import app from '../main';

const cacheStore = new Map();

function isFormData(data) {
  return typeof FormData !== 'undefined' && data instanceof FormData;
}

function normalizeValue(value) {
  if (Array.isArray(value)) {
    return value.map((item) => normalizeValue(item));
  }
  if (value && typeof value === 'object' && !(value instanceof Date)) {
    const sortedKeys = Object.keys(value).sort();
    return sortedKeys.reduce((acc, key) => {
      acc[key] = normalizeValue(value[key]);
      return acc;
    }, {});
  }
  return value;
}

function safeStringify(value) {
  if (value === undefined || value === null) {
    return '';
  }
  if (typeof value === 'string') {
    return value;
  }
  if (isFormData(value)) {
    const entries = [];
    value.forEach((v, k) => {
      entries.push([k, v]);
    });
    entries.sort((a, b) => {
      if (a[0] > b[0]) {
        return 1;
      }
      if (a[0] < b[0]) {
        return -1;
      }
      return 0;
    });
    return JSON.stringify(entries);
  }
  try {
    return JSON.stringify(normalizeValue(value));
  } catch (error) {
    console.warn('请求缓存序列化失败，使用空字符串代替。', error);
    return '';
  }
}

function createCacheKey(config) {
  const method = (config.method || 'get').toUpperCase();
  const url = config.url || '';
  if (isFormData(config.data)) {
    return null;
  }
  const paramsString = safeStringify(config.params);
  const dataString = safeStringify(config.data);
  return `${method}::${url}::${paramsString}::${dataString}`;
}

function buildCachedResponse(cacheEntry, config) {
  return {
    data: cacheEntry.data,
    status: cacheEntry.status,
    statusText: cacheEntry.statusText,
    headers: cacheEntry.headers,
    config,
    request: cacheEntry.request,
  };
}
// 转换form-data
function transformRequestData(data) {
  if (data instanceof FormData) {
    return data;
  }
  return qs.stringify(data);
}
// 创建axios实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  headers: {
    token: getUrlParam('token'),
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  transformRequest: [transformRequestData],
  timeout: 10000,
});
// 过滤请求
service.interceptors.request.use((config) => {
  const useCache = config.useCache === true;
  if (!useCache) {
    return config;
  }
  const cacheKey = createCacheKey(config);
  if (!cacheKey) {
    return config;
  }

  const cached = cacheStore.get(cacheKey);
  if (cached) {
    config.adapter = () => Promise.resolve(buildCachedResponse(cached, config));
    // eslint-disable-next-line no-underscore-dangle
    config.__fromCache = true;
    return config;
  }

  // eslint-disable-next-line no-underscore-dangle
  config.__cacheKey = cacheKey;
  return config;
});
// 过滤响应
service.interceptors.response.use((result) => {
  if (result.data.message === '401') {
    console.log(result);
    app.$toast.center('登录已过期,请删除小程序重新进入!');
    // 通知websocket关闭
    store.commit('app/setNeedLogin', true);
    return Promise.reject();
  }

  // eslint-disable-next-line no-underscore-dangle
  if (result.config && result.config.useCache === true && !result.config.__fromCache && result.config.__cacheKey) {
    // eslint-disable-next-line no-underscore-dangle
    cacheStore.set(result.config.__cacheKey, {
      data: result.data,
      status: result.status,
      statusText: result.statusText,
      headers: result.headers,
      request: result.request,
    });
  }
  return result.data.data;
});

export default service;
